#include "workflowxml.h"

#include <QXmlStreamReader>

CPortProperty *CPort::getProperty() const
{
    return property;
}

void CPort::setProperty(CPortProperty *value)
{
    property = value;
}

void CPort::addFlie(QString filePath)
{
    m_listFiles.push_back(filePath);
}

void CPort::deleteFile(QString filePath)
{
    m_listFiles.remove(filePath);
}


CPort::CPort(CPortProperty *_property, QObject *parent):property(_property),QObject(parent)
{

}

CPort::~CPort()
{
    qDebug()<<__func__;
    if(property)
    {
        delete property;
        property = nullptr;

    }
}

QPointF CPort::getPos() const
{

    return pos;
}

void CPort::setPos(const QPointF &value)
{
    pos = value;
}

CPort *CRelation::dstPort() const
{
    return m_dstPort;
}

void CRelation::setDstPort(CPort *dstPort)
{
    m_dstPort = dstPort;
}

CRelationProperty *CRelation::getProperty() const
{
    return property;
}

void CRelation::setProperty(CRelationProperty *value)
{
    property = value;
}

CRelation::CRelation(QObject *parent)
{

}

CRelation::CRelation(CRelationProperty *_property, CPort *_m_strPort, CPort *_m_dstPort, QObject *parent):property(_property),
    m_srcPort(_m_strPort),m_dstPort(_m_dstPort),QObject(parent)
{
    m_srcPort->getProperty()->direction = "in";
    m_dstPort->getProperty()->direction = "out";
}

CRelation::~CRelation()
{
    if(property)
    {
        delete property;
        property =nullptr;
    }
    qDebug()<<__func__;
}

CPort *CRelation::srcPort() const
{
    return m_srcPort;
}

void CRelation::setSrcPort(CPort *srcPort)
{
    m_srcPort = srcPort;
}

WorkFlowProperty *WorkFlow::getProperty() const
{
    return property;
}

void WorkFlow::setProperty(WorkFlowProperty *value)
{
    if(property!=nullptr)
    {
        delete property;
        property=nullptr;
    }
    property = value;
}

WorkFlowParam *WorkFlow::getParam() const
{
    return param;
}

void WorkFlow::setParam(WorkFlowParam *value)
{
//    if(param!=nullptr)
//    {
//        delete param;
//        param=nullptr;
//    }
    param = value;
}


std::list<CStep *> WorkFlow::getListStep() const
{
    return m_listStep;
}

void WorkFlow::removeCRelationContainCPort(CPort *cport)
{
    for(auto item : m_listRelations)
    {
        if(item->srcPort() == cport || item->dstPort() == cport)
        {

            removeCRelationAndCLink(item);
            break;
        }
    }
}

void WorkFlow::removeCRelationAndCLink(CRelation* crelation)
{
    bool flag = true;
    while(flag)
    {
        flag = false;
        for(auto it:m_listLinks)
        {
            if(it->relation() == crelation)
            {
                delteLink(it);
                flag = true;
                break;
            }
        }
    }
    this->deleteRelation(crelation);

}

CPort *WorkFlow::findCPortByName(const QString &name)
{
    for(auto cstep:m_listStep)
    {
        for(auto cport:cstep->m_listPort)
        {
            if(cport->getProperty()->name == name)
            {
                return cport;
            }
        }
    }
    return nullptr;
}

CRelation *WorkFlow::findCRelationByName(const QString &name)
{
    for(auto crelation:m_listRelations)
    {
        if(crelation->getProperty()->name == name)
        {
            return crelation;
        }
    }
    return nullptr;
}



std::list<CLink *> WorkFlow::getListLinks() const
{
    return m_listLinks;
}

WorkFlow::~WorkFlow()
{
    while(m_listStep.size()>0)
    {
        CStep* step = m_listStep.front();
        m_listStep.pop_front();
        delete step;
        step =nullptr;
    }
    while(m_listRelations.size()>0)
    {
        CRelation* relation = m_listRelations.front();
        m_listRelations.pop_front();

        delete relation;
        relation =nullptr;
    }
    while(m_listLinks.size()>0)
    {
        CLink* relation = m_listLinks.front();
        m_listLinks.pop_front();

        delete relation;
        relation =nullptr;
    }

}

WorkFlow::WorkFlow(WorkFlowProperty *_property)
{
    property = _property;
}


void WorkFlow::addStep(CStep *step)
{
    m_listStep.push_back(step);
}

void WorkFlow::deleteStep(CStep *step)
{
    m_listStep.remove(step);
    delete step;
    step = nullptr;
}

void WorkFlow::addRelation(CRelation *step)
{
    m_listRelations.push_back(step);
}

void WorkFlow::deleteRelation(CRelation *step)
{
    m_listRelations.remove(step);
    delete step;
    step = nullptr;
}

void WorkFlow::addLink(CLink *step)
{
    m_listLinks.push_back(step);
}

void WorkFlow::delteLink(CLink *step)
{
    m_listLinks.remove(step);

    delete step;
    step = nullptr;
}

bool WorkFlow::containCport(CPort *port)
{
    for(auto item: m_listLinks)
    {
        if(item->port() == port)
        {
            return true;
        }
    }
    return false;
}

QPointF CStep::getPos() const
{
    if(property)
    {
        return property->pos;

    }
    return QPointF(0,0);

}

void CStep::setPos(const QPointF &value)
{
    if(property)
    {
        property->pos = value;
    }
}

CStep::CStep(CStepProperty *_property,QObject* parent):QObject(parent)
{
    property = _property;
}

CStep::~CStep()
{
    qDebug()<<__func__;
    while(m_listAction.size()>0)
    {
        CAction* action = m_listAction.front();
        m_listAction.pop_front();
        delete action;
        action =nullptr;
    }
    while(m_listParam.size()>0)
    {
        CStepParam* param = m_listParam.front();
        m_listParam.pop_front();
        delete param;
        param =nullptr;
    }
    while(m_listFile.size()>0)
    {
        CStepFile* param = m_listFile.front();
        m_listFile.pop_front();
        delete param;
        param =nullptr;
    }
    while(m_listPort.size()>0)
    {
        CPort* param = m_listPort.front();
        m_listPort.pop_front();
        delete param;
        param =nullptr;
    }
    if(property)
    {
        delete property;
        property =nullptr;
    }
}

void CStep::addParam(CStepParam *param)
{
    m_listParam.push_back(param);
}

void CStep::deleteParam(CStepParam *param)
{
    m_listParam.remove(param);
    delete param;
    param = nullptr;
}

void CStep::addAction(CAction *action)
{
    m_listAction.push_back(action);
}

void CStep::deleteAction(CAction *action)
{
    m_listAction.remove(action);
    delete  action;
    action = nullptr;
}

void CStep::addFile(CStepFile *file)
{
    m_listFile.push_back(file);
}

void CStep::deleteFile(CStepFile *file)
{
    m_listFile.remove(file);
    delete  file;
    file = nullptr;
}

void CStep::addPort(CPort *port)
{
    m_listPort.push_back(port);
}

void CStep::deletePort(CPort *port)
{
    m_listPort.remove(port);
    delete  port;
    port = nullptr;
}

CStepProperty *CStep::getProperty() const
{
    return property;
}

void CStep::setProperty(CStepProperty *value)
{
    property = value;
}

void CStep::getListPort(std::list<CPort *>& _list)
{
    for(auto& item:m_listPort)
    {
        _list.push_back(item);
    }
}

CPort *CStep::findCPortByName(const QString &name)
{
    for(auto cport : m_listPort)
    {
        if(cport->getProperty()->name == name)
        {
            return cport;
        }
    }
    return nullptr;
}

CAction::CAction(CActionProperty *_property)
{
    property = _property;
}

CAction::~CAction()
{
    while(m_listPortsParams.size()>0)
    {
        auto item = m_listPortsParams.front();
        m_listPortsParams.pop_front();
        delete item;
        item=nullptr;
    }
//    while(m_listNormalParams.size()>0)
//    {
//        auto item = m_listNormalParams.front();
//        m_listNormalParams.pop_front();
//        delete item;
//        item=nullptr;
//    }
    if(property)
    {
        delete property;
        property =nullptr;
    }
}

CActionProperty *CAction::getProperty() const
{
    return property;
}

void CAction::setProperty(CActionProperty *value)
{
    property = value;
}

void CAction::addPortsParams(CActionParam *param)
{
    m_listPortsParams.push_back(param);
}

CRelation *CLink::relation() const
{
    return m_relation;
}

void CLink::setRelation(CRelation *relation)
{
    m_relation = relation;
}

CLink::CLink(CPort *_port, CRelation *_relation):m_port(_port),m_relation(_relation)
{

}

CLink::~CLink()
{
    qDebug()<<__func__;
    //        if(m_relation)
    //        {
    //            delete m_relation;
    //            m_relation = nullptr;
    //        }
}

CPort *CLink::port() const
{
    return m_port;
}

void CLink::setPort(CPort *port)
{
    m_port = port;
}


void WorkFlowXML::toXML(WorkFlow *workFlow)
{
    qDebug()<<"enter toXml";
    if(workFlow== nullptr || !workFlow->getProperty())
    {
        return;
    }

    WorkFlowProperty* workFlowProperty = workFlow->getProperty();

    QFile file(XMLFilePath+workFlowProperty->name+".xml");
    if(!file.open(QIODevice::ReadWrite | QIODevice::Truncate|QFile::Text ))
    {
        qDebug() << " Write Open false";
        return;
    }

    QDomDocument doc;
    //写入xml头部
    QDomProcessingInstruction instruction; //添加处理命令
    instruction=doc.createProcessingInstruction("xml","version=\"1.0\" encoding=\"UTF-8\"");
    doc.appendChild(instruction);

    //<------添加工作流属性
    QDomElement Workflow=doc.createElement("Workflow");
    Workflow.setAttribute("name ",workFlowProperty->name);
    Workflow.setAttribute("desp ",workFlowProperty->desp);
    Workflow.setAttribute("type ",workFlowProperty->type);
    doc.appendChild(Workflow);

    WorkFlowParam* workFlowParam = workFlow->getParam();
    if(workFlowParam)
    {
        QDomElement Property=doc.createElement("Property");

        QDomElement Author=doc.createElement("Author");
        QDomText author;
        author=doc.createTextNode(workFlowParam->m_author);

        QDomElement CreateTime=doc.createElement("CreateTime");
        QDomText createTime;
        createTime=doc.createTextNode(workFlowParam->dtCreateTime.toString("yyyy-MM-dd hh:mm:ss"));

        QDomElement Location=doc.createElement("Location");
        QDomText location;
        location=doc.createTextNode(workFlowParam->m_strLocation);

        Author.appendChild(author);
        CreateTime.appendChild(createTime);
        Location.appendChild(location);
        Property.appendChild(Author);
        Property.appendChild(CreateTime);
        Property.appendChild(Location);

        Workflow.appendChild(Property);
    }
    //添加工作流属性完成------>

    //<------添加组件
    for(auto step : workFlow->m_listStep)
    {
        CStepProperty* property = step->getProperty();
        QDomElement Step =doc.createElement("Step");
        if(property)
        {
            Step.setAttribute("name ",property->name);
            Step.setAttribute("desp ",property->desp);
            Step.setAttribute("id ",property->id);
            Step.setAttribute("type ",property->type);
            Step.setAttribute("pos ",QString("(%1,%2)").arg(property->pos.rx()).arg(property->pos.ry()));
            qDebug()<<property->pos;

            QDomElement Params =doc.createElement("Property");
            for(auto param: step->m_listParam)
            {
                QDomElement Param =doc.createElement("Param");
                Param.setAttribute("desp",param->desp);
                Param.setAttribute("name",param->name);
                Param.setAttribute("unit",param->unit);
                Param.setAttribute("type",param->type);
                Param.setAttribute("value",param->value);
                Params.appendChild(Param);
            }
            for(auto file: step->m_listFile)
            {
                QDomElement File =doc.createElement("File");
                File.setAttribute("desp",file->desp);
                File.setAttribute("name",file->name);
                File.setAttribute("value",file->value);
                Params.appendChild(File);
            }
            Step.appendChild(Params);

        }
        QDomElement Actions =doc.createElement("Actions");
        for(auto item:step->m_listAction)
        {
            QDomElement Action =doc.createElement("Action");
            Action.setAttribute("desp",item->property->name);
            Action.setAttribute("script",item->property->script);
            Action.setAttribute("type",item->property->type);

            QDomElement Params  =doc.createElement("Params");
            for(auto param:item->m_listPortsParams)
            {
                QDomElement Param  =doc.createElement("Param");
                Param .setAttribute("name",param->name);
                Param .setAttribute("refers",param->refers);
                Param .setAttribute("direction",param->direction);
                Params.appendChild(Param);
            }
//            for(auto param:item->m_listNormalParams)
//            {
//                QDomElement Param  =doc.createElement("Param");
//                Param .setAttribute("name",param->name);
//                Param .setAttribute("refers",param->refers);
//                Param .setAttribute("direction",param->direction);
//                Params.appendChild(Param);
//            }
            Action.appendChild(Params);
            Actions.appendChild(Action);
        }
        Step.appendChild(Actions);

        QDomElement Ports =doc.createElement("Ports");
        for(auto port : step->m_listPort)
        {
            QDomElement Port =doc.createElement("Port");
            Port.setAttribute("name",port->property->name);
            Port.setAttribute("refers",port->property->refers);
            Port.setAttribute("direction",port->property->direction);
            Port.setAttribute("location",port->property->location);
            Ports.appendChild(Port);
        }
        Step.appendChild(Ports);
        Workflow.appendChild(Step);

    }


    for(auto item : workFlow->m_listRelations)
    {
        QDomElement relation =doc.createElement("relation");
        relation.setAttribute("name",item->property->name);
        relation.setAttribute("type",item->property->type);
        Workflow.appendChild(relation);
    }

    for(auto item : workFlow->m_listLinks)
    {
        QDomElement link =doc.createElement("link");
        link.setAttribute("port",item->m_port->getProperty()->name);
        link.setAttribute("relation",item->m_relation->property->name);
        Workflow.appendChild(link);
    }

    QTextStream out_stream(&file);
    doc.save(out_stream,4); //缩进4格
    file.close();
}

WorkFlow *WorkFlowXML::toWorkFlow(QString xmlFile)
{
    WorkFlow* workFlow = nullptr;

    QDomDocument doc;
    QString error = "";
    int row = 0, column = 0;

    QFile file(xmlFile);
    if(!file.open(QIODevice::ReadOnly| QFile::Text))
    {
        qDebug()<<" open error";
        return nullptr;
    }

    if(!doc.setContent(&file, false, &error, &row, &column))
    {
        qDebug() << "parse file failed:" << row << "---" << column <<":" <<error;
        file.close();
        return nullptr;
    }
    file.close();


    QDomElement root = doc.documentElement();
    QString name ;
    QString type ;
    QString desp ;
    if(root.isNull())
    {
        return nullptr;
    }

    qDebug()<<root.tagName();
    if (root.hasAttribute("name")) {
       name = root.attributeNode("name").value();
    }
    if (root.hasAttribute("type")) {
       type = root.attributeNode("type").value();
    }
    if (root.hasAttribute("desp")) {
       desp = root.attributeNode("desp").value();
    }
    WorkFlowProperty* workFlowProperty = new WorkFlowProperty{name,desp,type};
    workFlow = new WorkFlow(workFlowProperty);


    QDomNodeList list = root.childNodes();
    for(int index = 0; index < list.count(); index++)
    {
        QDomNode list_node = list.item(index);
        QDomElement element = list_node.toElement();

        if(!element.isNull())
        {
            QString tag = element.tagName();
            if(tag == "Property")
            {
                WorkFlowParam* param = new WorkFlowParam;
                QDomNodeList list_2 = element.childNodes();
                for(int index_2 = 0; index_2 < list_2.count(); index_2++)
                {
                    QDomNode list_node_2 = list_2.item(index_2);
                    QDomElement element_2 = list_node_2.toElement();
                    if(!element_2.isNull())
                    {

                        QString tag = element_2.tagName();
                        if(tag == "Author")
                        {
                            param->m_author = element_2.text();
                            qDebug()<<element_2.text();
                        }
                        else if(tag == "Createtime")
                        {
                            param->dtCreateTime = QDateTime::fromString(element_2.text());
                            qDebug()<<element_2.text();
                        }
                        else if(tag == "Location")
                        {
                            param->m_strLocation = element_2.text();
                            //qDebug()<<element_2.text();
                        }
                        workFlow->setParam(param);
                    }
                }
            }
            else if(tag == "Step")
            {
                CStepProperty*  cstepProperty = new CStepProperty;
                CStep* cstep = nullptr;
                qDebug()<<element.tagName();
                if (element.hasAttribute("name")) {
                    cstepProperty->name = element.attributeNode("name").value();
                }
                if (element.hasAttribute("type")) {
                    cstepProperty->type = element.attributeNode("type").value();
                }
                if (element.hasAttribute("id")) {
                    cstepProperty->id = element.attributeNode("id").value().toInt();
                }
                if (element.hasAttribute("desp")) {
                    cstepProperty->desp = element.attributeNode("desp").value();
                }
                if (element.hasAttribute("pos")) {
                    QString pos = element.attributeNode("pos").value();
                    pos =  pos.mid(1,pos.size()-2);
                    QStringList list = pos.split(",");
                    cstepProperty->pos = QPointF(list.at(0).toInt(),list.at(1).toInt());
                    qDebug()<< "---" << cstepProperty->pos;
                }
                cstep = new CStep(cstepProperty);

                QDomNodeList list_2 = element.childNodes();
                for(int index_2 = 0; index_2 < list_2.count(); index_2++)
                {
                    QDomNode list_node_2 = list_2.item(index_2);
                    QDomElement element_2 = list_node_2.toElement();
                    if(!element_2.isNull())
                    {
                        qDebug()<<element_2.tagName() << ":" << element_2.text();
                        QString tag = element_2.tagName();
                        if(tag == "Property")
                        {

                            QDomNodeList list_3 = element_2.childNodes();
                            for(int index_3 = 0; index_3 < list_3.count(); index_3++)
                            {
                                QDomNode list_node_3 = list_3.item(index_3);
                                QDomElement element_3 = list_node_3.toElement();
                                if(!element_3.isNull())
                                {
                                    QString tag = element_3.tagName();
                                    if(tag == "Param")
                                    {
                                        CStepParam* cstepParam = new CStepParam;
                                        qDebug()<<element_3.tagName();
                                        if (element_3.hasAttribute("desp")) {
                                            cstepParam->desp = element_3.attributeNode("desp").value();
                                            //qDebug()<< "---" << "desp=" << element_3.attributeNode("desp").value();
                                        }
                                        if (element_3.hasAttribute("name")) {
                                            cstepParam->name = element_3.attributeNode("name").value();
                                            //qDebug()<< "---" << "name=" << element_3.attributeNode("name").value();
                                        }
                                        if (element_3.hasAttribute("unit")) {
                                            cstepParam->unit = element_3.attributeNode("unit").value();
                                            //qDebug()<< "---" << "unit=" << element_3.attributeNode("unit").value();
                                        }
                                        if (element_3.hasAttribute("type")) {
                                            cstepParam->type = element_3.attributeNode("type").value();
                                           // qDebug()<< "---" << "type=" << element_3.attributeNode("type").value();
                                        }
                                        if (element_3.hasAttribute("value")) {
                                            cstepParam->value = element_3.attributeNode("value").value();
                                            //qDebug()<< "---" << "value=" << element_3.attributeNode("value").value();
                                        }
                                        cstep->addParam(cstepParam);

                                    }
                                    else if(tag == "File")
                                    {
                                        CStepFile* cstepFile = new CStepFile;

                                        qDebug()<<element_3.tagName();
                                        if (element_3.hasAttribute("desp")) {
                                            cstepFile->desp = element_3.attributeNode("desp").value();
                                            //qDebug()<< "---" << "desp=" << element_3.attributeNode("desp").value();
                                        }
                                        if (element_3.hasAttribute("name")) {
                                            cstepFile->name = element_3.attributeNode("name").value();
                                            //qDebug()<< "---" << "name=" << element_3.attributeNode("name").value();
                                        }
                                        if (element_3.hasAttribute("value")) {
                                            cstepFile->value = element_3.attributeNode("value").value();
                                            //qDebug()<< "---" << "value=" << element_3.attributeNode("value").value();
                                        }
                                        cstep->addFile(cstepFile);
                                    }
                                }
                            }
                        }
                        else if(tag == "Actions")
                        {
                            if(element_2.hasChildNodes())
                            {

                                QDomNodeList list_3 = element_2.childNodes();
                                for(int index_3 = 0; index_3 < list_3.count(); index_3++)
                                {
                                    QDomNode list_node_3 = list_3.item(index_3);
                                    QDomElement element_3 = list_node_3.toElement();
                                    if(!element_3.isNull())
                                    {
                                        CActionProperty* catctionProperty= new CActionProperty;
                                        CAction* caction = nullptr;
                                        QString tag = element_3.tagName();
                                        if (element_3.hasAttribute("name")) {
                                            catctionProperty->name =  element_3.attributeNode("name").value();
                                            //qDebug()<< "---" << "name=" << element_3.attributeNode("name").value();
                                        }
                                        if (element_3.hasAttribute("script")) {
                                            catctionProperty->script =  element_3.attributeNode("script").value();
                                            //qDebug()<< "---" << "script=" << element_3.attributeNode("script").value();
                                        }
                                        if (element_3.hasAttribute("type")) {
                                            catctionProperty->type =  element_3.attributeNode("type").value();
                                            //qDebug()<< "---" << "type=" << element_3.attributeNode("type").value();
                                        }
                                        caction = new CAction(catctionProperty);


                                        if(element_3.hasChildNodes())
                                        {
                                            QDomElement element_4 = element_3.firstChild().toElement();
                                            {
                                                if(!element_4.isNull())
                                                {
                                                    QDomNodeList list_4 = element_4.childNodes();
                                                    for(int index_4 = 0; index_4 < list_4.count(); index_4++)
                                                    {
                                                        QDomNode list_node_4 = list_4.item(index_4);
                                                        QDomElement element_4 = list_node_4.toElement();
                                                        if(!element_4.isNull())
                                                        {
                                                            CActionParam* cactionParam = new CActionParam;
                                                            QString tag = element_4.tagName();
                                                            if (element_4.hasAttribute("name")) {
                                                                cactionParam->name =  element_4.attributeNode("name").value();
                                                                //qDebug()<< "---" << "name=" << element_4.attributeNode("name").value();
                                                            }
                                                            if (element_4.hasAttribute("refers")) {
                                                                cactionParam->refers =  element_4.attributeNode("refers").value();
                                                                //qDebug()<< "---" << "refers=" << element_4.attributeNode("refers").value();
                                                            }
                                                            if (element_4.hasAttribute("direction")) {
                                                                cactionParam->direction =  element_4.attributeNode("direction").value();
                                                                //qDebug()<< "---" << "direction=" << element_4.attributeNode("direction").value();
                                                            }
                                                            caction->addPortsParams(cactionParam);
                                                        }
                                                    }

                                                }
                                            }
                                        }
                                        cstep->addAction(caction);
                                    }
                                }
                            }
                        }
                        else if(tag == "Ports")
                        {
                            if(element_2.hasChildNodes())
                            {
//                                QDomElement element_3 = element_2.firstChild().toElement();
//                                {
//                                    if(!element_3.isNull())
//                                    {

                                        QDomNodeList list_3 = element_2.childNodes();
                                        for(int index_3 = 0; index_3 < list_3.count(); index_3++)
                                        {
                                            QDomNode list_node_3 = list_3.item(index_3);
                                            QDomElement element_3 = list_node_3.toElement();
                                            if(!element_3.isNull())
                                            {
                                                CPortProperty* cportProperty = new CPortProperty;

                                                QString tag = element_3.tagName();
                                                qDebug()<<element_3.tagName();
                                                if (element_3.hasAttribute("name")) {
                                                    cportProperty->name = element_3.attributeNode("name").value();
                                                    //qDebug()<< "---" << "name=" << element_4.attributeNode("name").value();
                                                }
                                                if (element_3.hasAttribute("refers")) {
                                                    cportProperty->refers = element_3.attributeNode("direction").value();
                                                    qDebug()<< "---" << "refers=" << element_3.attributeNode("refers").value();
                                                }
                                                if (element_3.hasAttribute("direction")) {
                                                    cportProperty->direction = element_3.attributeNode("direction").value();
                                                    //qDebug()<< "---" << "direction=" << element_4.attributeNode("direction").value();
                                                }
                                                if (element_3.hasAttribute("location")) {
                                                    QString location = element_3.attributeNode("location").value();
                                                    cportProperty->location = (CPortProperty::LOCATION)location.toInt();
                                                    //qDebug()<< "---" << "direction=" << element_4.attributeNode("direction").value();
                                                }
                                                CPort* cport = new CPort(cportProperty);
                                                cstep->addPort(cport);
                                            }
                                        }
//                                    }
//                                }
                            }
                        }
                    }
                }
                workFlow->addStep(cstep);

            }
            else if(tag == "relation")
            {
                CRelation* crelation = new CRelation;
                CRelationProperty* crelationProperty = new CRelationProperty;
                if (element.hasAttribute("name"))
                {
                    crelationProperty->name = element.attributeNode("name").value();
                }
                if (element.hasAttribute("type"))
                {
                    crelationProperty->type = element.attributeNode("type").value();
                }
                crelation->setProperty(crelationProperty);
                workFlow->addRelation(crelation);
            }
            else if(tag == "link")
            {
                CLink* clink = new CLink;
                CPort* cport = nullptr;
                CRelation* crelation  = nullptr;
                if (element.hasAttribute("port"))
                {
                    cport = workFlow->findCPortByName(element.attributeNode("port").value());

                }
                if (element.hasAttribute("relation"))
                {
                    crelation = workFlow->findCRelationByName(element.attributeNode("relation").value());

                }
                if(cport != nullptr)
                {
                    clink->setPort(cport);
                    clink->setRelation(crelation);
                    if(cport->getProperty()->direction == "in")
                    {
                        crelation->setSrcPort(cport);
                    }
                    else
                    {
                        crelation->setDstPort(cport);
                    }

                }

                workFlow->addLink(clink);
            }
        }
    }


    return workFlow;
}

bool WorkFlowXML::CheckWFIntegrity(WorkFlow *workFlow)
{
    for(auto cstep:workFlow->m_listStep)
    {
        if(cstep->property->type == "WFConditionStep" || cstep->property->type == "WFLoopStep")
        {
            int inCount=0;
            int outCount=0;
            for(auto cport:cstep->m_listPort)
            {
                if(cport->property->direction == "out")
                {
                    outCount++;
                }
                if(cport->property->direction == "in")
                {
                    inCount++;
                }
            }
            if(!(outCount != 2)||inCount<1)
            {
                return false;
            }
        }
        else
        {
            bool inValid=false;
            bool outValid=false;
            for(auto cport:cstep->m_listPort)
            {
                if(cport->property->direction == "in")
                {
                    inValid = true;
                }
                if(cport->property->direction == "out")
                {
                    outValid = true;
                }
            }
            if(!inValid||!outValid)
            {
                return false;
            }
        }
    }

    //完成性校验
    for(auto cstep:workFlow->m_listStep)
    {

        int endCount = 0;
        int startCount = 0;
        int conditionCount = 0;
        if(cstep->getProperty()->type  == "WFBeginStep")
        {
            int startConut = 0;
            if(startConut>0)
            {
                return false;
            }
            if(cstep->m_listPort.size() == 1)
            {
                CPort* cport = cstep->m_listPort.front();
                {
                    CPortProperty* cportProperty = cport->getProperty();
                    if(cportProperty->refers.isEmpty() && cportProperty->direction =="out")
                    {
                        startConut++;
                        break;
                    }
                }
            }

        }
        else if(cstep->getProperty()->type  == "WFEndStep")
        {

            if(endCount>0)
            {
                return false;
            }
            if(cstep->m_listPort.size() == 1)
            {
                CPort* cport = cstep->m_listPort.front();
                {
                    CPortProperty* cportProperty = cport->getProperty();
                    if(cportProperty->refers.isEmpty() && cportProperty->direction =="in")
                    {
                        endCount++;
                        break;
                    }
                }
            }
        }
        else if(cstep->getProperty()->type  == "WFConditionStep")
        {
            int inCount =0;
            int outCount =0;
            for(auto cport:cstep->m_listPort)
            {
                if(cport->getProperty()->direction == "in")
                {
                    inCount++;
                }
                else if(cport->getProperty()->direction == "out")
                {
                    outCount++;
                }
                int conditionCount = 0;

            }
        }
    }

    //逻辑性校验

    //一致性校验


}

